"""
项目数据模型

定义项目的基本信息和属性。
"""

from dataclasses import dataclass
from datetime import date
from typing import Optional
from enum import Enum


class ProjectPriority(Enum):
    """项目优先级枚举"""
    VERY_LOW = 1
    LOW = 2
    MEDIUM = 3
    HIGH = 4
    VERY_HIGH = 5


class ProjectStatus(Enum):
    """项目状态枚举"""
    PLANNING = "planning"
    IN_PROGRESS = "in_progress"
    ON_HOLD = "on_hold"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


@dataclass
class Project:
    """
    项目信息模型

    Attributes:
        project_id: 项目唯一标识符
        project_name: 项目名称
        start_date: 项目开始日期
        end_date: 项目结束日期
        phase: 项目阶段信息
        priority: 项目优先级（1-5，5为最高）
        description: 项目描述
        status: 项目状态
        budget: 项目预算（可选）
        client: 客户信息（可选）
        manager: 项目经理（可选）
    """
    project_id: str
    project_name: str
    start_date: date
    end_date: date
    phase: Optional[str] = None
    priority: ProjectPriority = ProjectPriority.MEDIUM
    description: Optional[str] = None
    status: ProjectStatus = ProjectStatus.PLANNING
    budget: Optional[float] = None
    client: Optional[str] = None
    manager: Optional[str] = None

    def __post_init__(self):
        """数据验证"""
        if self.start_date >= self.end_date:
            raise ValueError("项目开始日期必须早于结束日期")

        if not self.project_id.strip():
            raise ValueError("项目ID不能为空")

        if not self.project_name.strip():
            raise ValueError("项目名称不能为空")

    @property
    def duration_days(self) -> int:
        """计算项目持续天数"""
        return (self.end_date - self.start_date).days + 1

    @property
    def duration_months(self) -> float:
        """计算项目持续月数（近似）"""
        return self.duration_days / 30.0

    def is_active_on_date(self, check_date: date) -> bool:
        """检查指定日期项目是否活跃"""
        return self.start_date <= check_date <= self.end_date

    def overlaps_with(self, other_project: 'Project') -> bool:
        """检查与其他项目是否有时间重叠"""
        return not (self.end_date < other_project.start_date or
                   self.start_date > other_project.end_date)

    def to_dict(self) -> dict:
        """转换为字典格式"""
        return {
            'project_id': self.project_id,
            'project_name': self.project_name,
            'start_date': self.start_date.isoformat(),
            'end_date': self.end_date.isoformat(),
            'phase': self.phase,
            'priority': self.priority.value,
            'description': self.description,
            'status': self.status.value,
            'budget': self.budget,
            'client': self.client,
            'manager': self.manager,
            'duration_days': self.duration_days,
            'duration_months': round(self.duration_months, 2)
        }

    @classmethod
    def from_dict(cls, data: dict) -> 'Project':
        """从字典创建项目实例"""
        # 处理日期字段
        if isinstance(data['start_date'], str):
            data['start_date'] = date.fromisoformat(data['start_date'])
        if isinstance(data['end_date'], str):
            data['end_date'] = date.fromisoformat(data['end_date'])

        # 处理枚举字段
        if 'priority' in data and isinstance(data['priority'], int):
            data['priority'] = ProjectPriority(data['priority'])
        if 'status' in data and isinstance(data['status'], str):
            data['status'] = ProjectStatus(data['status'])

        # 移除计算字段
        computed_fields = ['duration_days', 'duration_months']
        for field in computed_fields:
            data.pop(field, None)

        return cls(**data)